package com.toncen.samepms.util;

import java.util.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.toncen.samepms.common.ComitConstant;
import com.toncen.samepms.system.domain.ErrorLogger;
import com.sky.common.http.HTTPUtils;
import com.sky.common.properties.PropertiesUtils;
import com.sky.common.string.StringUtils;

/**
 * ������־����
 * 
 * @author tch
 * 
 */
public class ErrorUtils {

	private static Log logger = LogFactory.getLog(ErrorUtils.class);

	/**
	 * ���������־�����Ϣ(�������쳣����ǰִ��ҳ���ַ��Ϣ�ȴ���request��Χ�У�����ת��������������ʾҳ��)
	 * ��jsp/servlet/filterִ��ҵ�����ʱ���׳��쳣����catch������ô˷���
	 * 
	 * @param request
	 * @param response
	 * @param throwable
	 */
	public static void dealwithError(HttpServletRequest request, HttpServletResponse response, Throwable throwable) {
		setThrowable(request, response, throwable);// ���쳣��ӵ�request��
		setHandlerURL(request, response);// �ѵ�ǰҳ����Ϣ��ӵ�request��
		String errorPage = "/error/errorPage.jsp";
		try {
			// ��ȡ���������ļ������õĹ���������ʾҳ���ַ
			if (!StringUtils.isEmpty(PropertiesUtils.getParameter(ComitConstant.ERROR_PROPERTIES_FILE, ComitConstant.ERROR_ERRORPAGE_KEY))) {
				errorPage = PropertiesUtils.getParameter(ComitConstant.ERROR_PROPERTIES_FILE, ComitConstant.ERROR_ERRORPAGE_KEY);
			} else {
				logger.debug("���������ļ�[" + ComitConstant.ERROR_PROPERTIES_FILE + "]��û���ҵ�key[" + ComitConstant.ERROR_ERRORPAGE_KEY + "]����ֵΪ��...");
			}
		} catch (Exception e1) {
			logger.debug("���������ļ�[" + ComitConstant.ERROR_PROPERTIES_FILE + "]������...");
		}
		RequestDispatcher rd = request.getRequestDispatcher(errorPage);
		try {
			rd.forward(request, response);// ת��������������ҳ��
		} catch (Exception e) {
			e.printStackTrace();
			throw new IllegalArgumentException("������ҳ�治����[" + errorPage + "]...");
		}
	}

	/**
	 * �ͷŴ�����־�����Ϣ �ڴ����������ͷ���Դ(����request��Χ���쳣����ǰִ��ҳ���ַ��Ϣ��)
	 * 
	 * @param request
	 * @param response
	 */
	public static void releaseError(HttpServletRequest request, HttpServletResponse response) {
		request.removeAttribute(ComitConstant.ERROR_EXCEPTION_REQUEST_ATTRIBUTE);// �ͷ��쳣
		request.removeAttribute(ComitConstant.ERROR_HANDLERURL_REQUEST_ATTRIBUTE);// �ͷŴ���ҳ��·��
	}

	/**
	 * ���쳣�����󡢻ظ������й���ErrorInfo����
	 * 
	 * @param request
	 * @param response
	 * @param throwable
	 * @return
	 */
	public static ErrorLogger builderErrorLogger(HttpServletRequest request, HttpServletResponse response, Throwable throwable) {
		if (throwable == null) {
			throw new IllegalArgumentException("û���κ��쳣...");
		}
		ErrorLogger error = new ErrorLogger();
		error.setId(System.currentTimeMillis());// �Ե�ǰϵͳ�ĺ�������Ϊ����
		error.setHappenTime(new Date());
		error.setHandlerUrl(getHandlerURL(request, response));
		String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
		String refererUrl = request.getHeader("referer");
		if (!StringUtils.isEmpty(refererUrl)) {
			error.setRefererUrl(refererUrl.replaceFirst(basePath, ""));
		}
		error.setParameter(HTTPUtils.getParameterMap(request).toString());
		error.setClientIp(HTTPUtils.getRemoteAddr(request));
		error.setErrorType(throwable.getClass().getName());
		error.setStacktrace(getStackTrace(throwable));
		return error;
	}

	/**
	 * ��ȡʵ�ʵ��쳣���������쳣�����ڣ����ȡrequest�е�ComitConstant.ERROR_EXCEPTION_REQUEST_ATTRIBUTE
	 * 
	 * @param request
	 * @param response
	 * @param throwable
	 * @return
	 */
	public static Throwable getThowable(HttpServletRequest request, HttpServletResponse response, Throwable throwable) {
		if (throwable == null) {// �����ĳ�ʼ�쳣û�У���ȡrequest�е��쳣
			Throwable requestThrowable = (Throwable) request.getAttribute(ComitConstant.ERROR_EXCEPTION_REQUEST_ATTRIBUTE);
			if (requestThrowable == null) {
				throw new IllegalArgumentException("û������request�е��쳣����[" + ComitConstant.ERROR_EXCEPTION_REQUEST_ATTRIBUTE + "]...");
			}
			return requestThrowable;
		} else {
			return throwable;
		}
	}

	/**
	 * ����ʵ�ʵ��쳣�����쳣����request�У��������ΪComitConstant.ERROR_EXCEPTION_REQUEST_ATTRIBUTE
	 * 
	 * @param request
	 * @param response
	 * @param throwable
	 */
	public static void setThrowable(HttpServletRequest request, HttpServletResponse response, Throwable throwable) {
		request.setAttribute(ComitConstant.ERROR_EXCEPTION_REQUEST_ATTRIBUTE, throwable);
	}

	/**
	 * ��ȡ����ҳ��·��
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	public static String getHandlerURL(HttpServletRequest request, HttpServletResponse response) {
		String handlerURL = (String) request.getAttribute(ComitConstant.ERROR_HANDLERURL_REQUEST_ATTRIBUTE);
		if (StringUtils.isEmpty(handlerURL)) {
			throw new IllegalArgumentException("û������request�еĴ���ҳ��·������[" + ComitConstant.ERROR_HANDLERURL_REQUEST_ATTRIBUTE + "]...");
		}
		return handlerURL;
	}

	/**
	 * ���ô���ҳ��·�����Ѵ���ҳ��·������request�У��������ΪComitConstant.ERROR_HANDLERURL_REQUEST_ATTRIBUTE
	 * 
	 * @param request
	 * @param response
	 */
	public static void setHandlerURL(HttpServletRequest request, HttpServletResponse response) {
		request.setAttribute(ComitConstant.ERROR_HANDLERURL_REQUEST_ATTRIBUTE, request.getRequestURI().replaceFirst(request.getContextPath(), ""));
	}

	/**
	 * ��ȡ��ҳ��ַ
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	public static String getIndexURL(HttpServletRequest request, HttpServletResponse response) {
		String indexURL = "/index.jsp";
		try {
			// ��ȡ���������ļ������õĹ���������ʾҳ���ַ
			if (!StringUtils.isEmpty(PropertiesUtils.getParameter(ComitConstant.ERROR_PROPERTIES_FILE, ComitConstant.ERROR_INDEXURL_KEY))) {
				indexURL = PropertiesUtils.getParameter(ComitConstant.ERROR_PROPERTIES_FILE, ComitConstant.ERROR_INDEXURL_KEY);
			} else {
				logger.debug("���������ļ�[" + ComitConstant.ERROR_PROPERTIES_FILE + "]��û���ҵ�key[" + ComitConstant.ERROR_INDEXURL_KEY + "]����ֵΪ��...");
			}
		} catch (Exception e1) {
			logger.debug("���������ļ�[" + ComitConstant.ERROR_PROPERTIES_FILE + "]������...");
		}
		return indexURL;
	}

	/**
	 * ��ȡThrowable�Ķ�ջ��Ϣ
	 * 
	 * @param throwable
	 * @return
	 */
	public static String getStackTrace(Throwable throwable) {
		if (throwable == null) {
			return "";
		}
		StringBuffer strStackTrace = new StringBuffer();
		strStackTrace.append(throwable);
		// strStackTrace.append("\n");
		strStackTrace.append("<br>");
		// strStackTrace.append("\n");
		StackTraceElement[] stackTraceElements = throwable.getStackTrace();
		for (StackTraceElement stackTraceElement : stackTraceElements) {
			strStackTrace.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
			strStackTrace.append("\tat ");
			strStackTrace.append(stackTraceElement.toString());
			strStackTrace.append("<br>");
			// strStackTrace.append("\n");
		}
		Throwable ourCause = throwable.getCause();
		if (ourCause != null) {
			strStackTrace.append("Caused by: ");
			strStackTrace.append(getStackTrace(throwable.getCause()));
			// strStackTrace.append("\n");
		}
		return strStackTrace.toString();
	}
}
